package com.ideaaedi.zoo.diy.artifact.websocket.core;

import org.springframework.beans.factory.SmartInitializingSingleton;

import javax.annotation.Nullable;
import java.util.concurrent.TimeUnit;

/**
 * websocket心跳监测器
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.4.3
 */
public class WebSocketHeartbeatRunner implements SmartInitializingSingleton, Runnable {
    
    public static final ThreadLocal<Boolean> HEARTBEAT_RUNNER_CALL = new ThreadLocal<>();
    
    @Nullable
    private final WebSocketCallback websocketCallback;
    
    public WebSocketHeartbeatRunner(@Nullable WebSocketCallback websocketCallback) {
        this.websocketCallback = websocketCallback;
    }
    
    @Override
    public void afterSingletonsInstantiated() {
        Thread thread = new Thread(this);
        thread.setDaemon(true);
        thread.start();
    }
    
    /**
     * 检测客户端是否还"活着"
     */
    @Override
    public void run() {
        while (true) {
            try {
                HEARTBEAT_RUNNER_CALL.set(true);
                AbstractWebSocketEndpoint.CLIENT_SESSION_MAP.forEach((sessionUuid, session) -> {
                    Throwable throwable = AbstractWebSocketEndpoint.ifAlive(session);
                    if (throwable != null) {
                        AbstractWebSocketEndpoint.removeLocalSession(sessionUuid, websocketCallback);
                    }
                });
            } finally {
                HEARTBEAT_RUNNER_CALL.set(false);
            }
            try {
                TimeUnit.SECONDS.sleep(180);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
